package model.algorithmes;

import model.value.VersionnedValue;

import model.observer.SensorObserver;
import model.subject.Sensor;
import model.subject.Lockable;

/**
 * Implémentation de l'interface SpreadingAlgorithme, pour une diffusion atomique des valeurs. Ici, il s'agit de bloquer le capteur tant que tous ses 
 * observeurs n'ont pas été mis à jour.
 */
public class AtomicSpreadingImpl implements SpreadingAlgorithme {

	private VersionnedValue currentValue;
		
	private Sensor sensor;
	private int count;	// Nombre de diffusions en cours
	
	@Override
	public void configure(Sensor sensor) {
		this.sensor = sensor;

		count = 0;
	}

	@Override
	public VersionnedValue getValue() {
		if(count > 0) {
			count--;
		}
		
		if(count == 0) {	// Si il n'y a plus de diffusion en cours alors on débloque le capteur
			((Lockable)sensor).allowChanges();
		}
		
		return currentValue;
	}
	
	@Override
	public void execute() {
		if(count == 0) {	// Si il n'y a pas de diffusion en cours alors on bloque le capteur et on lance la nouvelle diffusion
			((Lockable)sensor).blockChanges();
			currentValue = sensor.getRealValue();

			for(SensorObserver observer : sensor.getObservers()) {
				observer.update(sensor);
				count++;
			}
		}
	}

	@Override
	public void setValue(int value) {
		if(count == 0) {
			sensor.setRealValue(value);
		}
	}

}
